package com.hdsx.validator.validate.aspect;

import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import com.hdsx.validator.validate.annotation.Validator;
import com.hdsx.validator.validate.handler.DefaultHandler;
import com.hdsx.validator.validate.handler.DefaultValidator;
import com.hdsx.validator.validate.handler.IHandler;

@Aspect
@Component
public class ValidateAspect {
	
	 @Resource
	 private IHandler handler;
	//声明切入点
     @Pointcut(value="@annotation(com.hdsx.validator.validate.annotation.Validator)") 
     public void writeLog(){};
     
     //返回后通知  
     @AfterReturning("writeLog()")
	 public void doAfterReturning(ProceedingJoinPoint  jp) {
	 	try {
	 		handler.register("GIS_QL", new DefaultValidator() );
    	 	/**
    	 	 * 判断方法名和参数长度是否相同（主要用来区分重载方法，以免记录错误）
    	 	 */
	 		String methodName = jp.getSignature().getName();//得到当前方法的方法名
	 		Method[] methods = jp.getTarget().getClass().getDeclaredMethods();
	 		Object[] args = jp.getArgs();//获得参数对象数组
	 		Method realMethod = null;
    	 	for(Method method:methods){
    	 		if(method.getName().equals(methodName) && method.getParameterTypes().length == args.length){
    	 			boolean flag = true;
    	 			//遍历所有参数类型是否一致 注意List ArrayList ;Map HashMap问题
    	 			for(int i=0;i<method.getParameterTypes().length;i++){
    	 				String typeName = getArcsTypeName(args[i]);
    	 				if(!method.getParameterTypes()[i].getName().equals(typeName)){
    	 					flag = false;
    	 					break;
    	 				}
    	 			}
	 				if(flag){
	 					realMethod = method;
	    	 			break;
	 				}
    	 		}
    	 	}
    	 	if(realMethod!=null)
    	 	{
    	 		Validator mark = realMethod.getAnnotation(Validator.class);//得到注解
        	 	String alias=mark.alias();
        	 	Object obj=jp.proceed(args);
        	 	if(obj instanceof Collection)
        	 	{
        	 		Collection collection=(Collection) obj;
        	 		Iterator iter=collection.iterator();
        	 		while(iter.hasNext())
        	 		{
        	 			handler.validate(alias, iter.next(), null);	
        	 		}
        	 	}
        	 	else 
        	 	{
        	 		handler.validate(alias, args[0], null);	
        	 	}
    	 	}
    	 	/**
    	 	 * 根据注解传入参数执行相应操作
    	 	 */
		} catch (Throwable e) {
			e.printStackTrace();
		}
    } 
    
	/**
	 * 根据参数对象获取参数接口类型
	 * @param obj
	 * @return
	 */
 	private String getArcsTypeName(Object obj){
 		String typeName = "";
 		if(obj instanceof List){
 			typeName = "java.util.List";
 		}else if(obj instanceof Set){
 			typeName = "java.util.Set";
 		}else if(obj instanceof Map){
 			typeName = "java.util.Map";
 		}else{
 			typeName = obj.getClass().getName();
 		}
 		return typeName;
 	}
}
